package com.springsummer.information.green.beans;




import java.util.Date;

public abstract class AbstractApplicationContext implements ApplicationContext{

    protected String displayName;

    @Override
    public void refresh() throws Exception {
        synchronized (this) {


            try {


                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

                // Prepare the bean factory for use in this context.
                prepareBeanFactory(beanFactory);

                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                //invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);


                // Initialize message source for this context.
                //initMessageSource();

                // Initialize event multicaster for this context.
                //initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh(beanFactory);

                // Check for listener beans and register them.
                //registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                //finishRefresh();
            } catch (Exception ex) {


                throw ex;
            }


        }
    }


    protected void onRefresh(ConfigurableListableBeanFactory beanFactory) {
        //Initialize other special beans in specific context subclasses.
    }

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

    }

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

    }

    protected  abstract void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) throws Exception ;

    protected  abstract void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) throws Exception ;


    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() throws Exception{
        refreshBeanFactory();
        return getBeanFactory();
    }

    protected abstract void refreshBeanFactory() throws Exception;

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }


    public String getDisplayName() {
        return this.displayName;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(getDisplayName());
        stringBuilder.append(", started on ").append(new Date(getStartupDate()));
        return stringBuilder.toString();
    }

}


